package com.epsilon.pos.principal.ventas.delegate;

import java.awt.Graphics;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.text.SimpleDateFormat;
import java.util.Map;

import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;

import com.epsilon.pos.impuestos.model.Impuesto;
import com.epsilon.pos.principal.ventas.model.ArticuloUnitarioVenta;
import com.epsilon.pos.principal.ventas.model.CorteDeCaja;
import com.epsilon.pos.principal.ventas.model.Venta;
import com.epsilon.pos.principal.ventas.model.VentasPrincipalException;

public class VentasUtil {
	public static SimpleDateFormat	format		= new SimpleDateFormat( "dd/MMM/yyyy h:mm aa" );
	public static final int			_ID_ACTIVA_	= 0;

	private VentasUtil() {
	}

	public static Float getTotalDeArticuloUnitarioVenta( ArticuloUnitarioVenta articulo ) {
		return (articulo.getCantidad() * articulo.getArticuloUnitario().getPrecioUnitario());
	}

	public static Float getSubTotal( Map< String, ArticuloUnitarioVenta > mapaDeArticulos ) {
		Float subTotal = 0.0F;

		for( ArticuloUnitarioVenta articulos : mapaDeArticulos.values() ) {
			subTotal += getTotalDeArticuloUnitarioVenta( articulos );
		}

		return subTotal;
	}

	public static Float getImpuestos( Map< String, ArticuloUnitarioVenta > mapaDeArticulos ) {
		Float impuestos = 0.0F;

		for( ArticuloUnitarioVenta articulos : mapaDeArticulos.values() ) {
			if( articulos.getArticuloUnitario().getListaDeImpuestos() != null && !articulos.getArticuloUnitario().getListaDeImpuestos().isEmpty() ) {
				for( Impuesto i : articulos.getArticuloUnitario().getListaDeImpuestos() ) {
					impuestos += (i.getPorcentaje() * (getTotalDeArticuloUnitarioVenta( articulos )) * 0.01F);
				}
			}
		}

		return impuestos;
	}

	public static Float getTotal( Map< String, ArticuloUnitarioVenta > mapaDeArticulos ) {
		return getSubTotal( mapaDeArticulos ) + getImpuestos( mapaDeArticulos );
	}

	public static String getStringFromFloat( Float numero ) {
		return (numero != null ? String.format( "%.2f", numero ) : null);
	}

	public static void imprimirTicket( Venta venta ) throws VentasPrincipalException {
		try {

			String ticket = ":::::::::BALNEARIO 'LAS FUENTES':::::::::\r\n";
			ticket += "-----------------------------------------\r\n";
			ticket += "Responsable: " + venta.getContextoDeAplicacion().getUsuario().getNombreCortoDeUsuario() + "\r\n";
			ticket += "Lugar      : " + venta.getContextoDeAplicacion().getLugarDeEjecucion().getDescripcion() + "\r\n";
			ticket += "Fecha/hora : " + format.format( venta.getFechaDeVenta() ).toUpperCase() + "\r\n";
			
			ticket += "-----------------------------------------\r\n";
			
			for( int i = 0; i < 1; i++ ) {
				ticket += "\r\n";
			}

			for( ArticuloUnitarioVenta a : venta.getMapaDeArticulosUnitariosComprados().values() ) {
				ticket += padRight( a.getCantidad() + " x " + a.getArticuloUnitario().getDescripcion(), 30 );
				ticket += padLeft( getStringFromFloat( a.getCantidad() * a.getArticuloUnitario().getPrecioUnitario() ), 7 ) + "\r\n";
			}

			ticket += "\r\nTotal    : " + getStringFromFloat( getTotal( venta.getMapaDeArticulosUnitariosComprados() ) ) + "\r\n";
			ticket += "-----------------------------------------\r\n";
			ticket += "Recibido : " + getStringFromFloat( venta.getMontoRecibido() ) + "\r\n";
			ticket += "Su cambio: " + getStringFromFloat( venta.getMontoDeSalida() ) + "\r\n";

			for( int i = 0; i < 2; i++ ) {
				ticket += "\r\n";
			}

			ticket += "ticket: " + venta.getCodigoDeTicket() + "\r\n\r\n";
			
			ticket += (venta.getObservaciones() != null && !venta.getObservaciones().trim().isEmpty() ? venta.getObservaciones().trim() : "");

			imprimirTicket( ticket );
		} catch( Exception e ) {
			e.printStackTrace();
			throw new VentasPrincipalException( "Error al imprimir el ticket: " + e.getMessage() );
		}
	}
	
	public static void imprimirTicket( CorteDeCaja corteDeCaja ) throws VentasPrincipalException {
		
		try {
			String ticket = ":::::::::BALNEARIO 'LAS FUENTES':::::::::\r\n";
			ticket += "-----------------------------------------\r\n";
			ticket += "Responsable: " + corteDeCaja.getContextoDeAplicacion().getUsuario().getNombreCortoDeUsuario() + "\r\n";
			ticket += "Lugar      : " + corteDeCaja.getContextoDeAplicacion().getLugarDeEjecucion().getDescripcion() + "\r\n";
			ticket += "Fecha/hora : " + format.format( corteDeCaja.getFechaDeCorte() ).toUpperCase() + "\r\n";
			
			ticket += "-----------------------------------------\r\n";
			ticket += "Corte de caja: " + getStringFromFloat( corteDeCaja.getMontoDeCorte() ) + "\r\n";
			ticket += "-----------------------------------------\r\n";
			
			for( int i = 0; i < 4; i++ ) {
				ticket += "\r\n";
			}
			
			ticket += (corteDeCaja.getObservaciones() != null && !corteDeCaja.getObservaciones().trim().isEmpty() ? corteDeCaja.getObservaciones() : "" );

			for( int i = 0; i < 4; i++ ) {
				ticket += "\r\n";
			}
			
			imprimirTicket( ticket );
		}
		catch( Exception e ) {
			e.printStackTrace();
			throw new VentasPrincipalException( "Error al imprimir el ticket: " + e.getMessage() );
		}
	}

	private static void imprimirTicket( String ticket ) throws PrinterException, PrintException {
		PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();

		PrintService [] printServices = PrintServiceLookup.lookupPrintServices( null, null );
		PrintService impresoraSeleccionada = null;

		DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;

		Doc mydoc = new SimpleDoc( ticket.getBytes(), flavor, null );

		for( PrintService impresora : printServices ) {

			if( impresora.getName().trim().contains( "VENDOR THERMAL PRINTER" ) ) {
				impresoraSeleccionada = impresora;
			}
		}

		if( impresoraSeleccionada != null ) {
			DocPrintJob job = impresoraSeleccionada.createPrintJob();
			job.print( mydoc, pras );
			cortarTicket( impresoraSeleccionada );
		}
	}

	private static void cortarTicket( PrintService impresora ) throws PrinterException {
		PrinterJob pj = PrinterJob.getPrinterJob();
		pj.setPrintService( impresora );
		pj.setPrintable( new Printable() {
			@Override
			public int print( Graphics graphics, PageFormat pageFormat, int pageIndex ) throws PrinterException {
				if( pageIndex != 0 )
					return NO_SUCH_PAGE;

				return PAGE_EXISTS;
			}

		} );

		pj.print();
	}

	public static String padRight( String s, int n ) {
		return String.format( "%1$-" + n + "s", s );
	}

	public static String padLeft( String s, int n ) {
		return String.format( "%1$#" + n + "s", s );
	}
}